﻿using System;

namespace dPet.Domain.Models
{
	using Hangerd;
	using Hangerd.Entity;
	using Hangerd.Utility;

	public abstract class OrderBase : EntityBase
	{
		#region Public Properties

		/// <summary>
		/// 订单号
		/// </summary>
		[RecordModify]
		public string OrderNumber { get; protected set; }

		/// <summary>
		/// 所属医院ID
		/// </summary>
		public string HospitalId { get; private set; }

		/// <summary>
		/// 订单状态
		/// </summary>
		[RecordModify]
		public OrderStatus Status { get; private set; }

		/// <summary>
		/// 下单操作人
		/// </summary>
		[RecordModify]
		public string Creator { get; private set; }

		/// <summary>
		/// 下单时间
		/// </summary>
		public DateTime CreateTime { get; private set; }

		/// <summary>
		/// 支付方式
		/// </summary>
		[RecordModify]
		public PaymentMethod PaymentMethod { get; private set; }

		/// <summary>
		/// 完成人
		/// </summary>
		[RecordModify]
		public string Completer { get; private set; }

		/// <summary>
		/// 完成时间
		/// </summary>
		public DateTime CompleteTime { get; private set; }

		/// <summary>
		/// 总金额
		/// </summary>
		[RecordModify]
		public decimal TotalAmount { get; protected set; }

		#endregion

		#region Constructors

		internal OrderBase() { }

		internal OrderBase(Hospital hospital, string creator)
		{
			this.OrderNumber = GenerateOrderNumber(hospital);
			this.HospitalId = hospital.Id;
			this.Creator = creator;
			this.CreateTime = DateTime.Now;
			this.CompleteTime = new DateTime(2999, 1, 1);
		}

		#endregion

		#region Protected Methods

		protected abstract string GenerateOrderNumber(Hospital hospital);

		/// <summary>
		/// 取消订单修改状态
		/// </summary>
		protected virtual void InternalCancel(string @operator)
		{
			this.CheckStatus(OrderStatus.Init);

			this.Status = OrderStatus.Canceled;
			this.Completer = @operator;
			this.CompleteTime = DateTime.Now;
		}

		/// <summary>
		/// 完成订单修改状态
		/// </summary>
		protected virtual void InternalComplete(PaymentMethod paymentMethod, string completer)
		{
			this.CheckStatus(OrderStatus.Init);

			this.Status = OrderStatus.Completed;
			this.PaymentMethod = paymentMethod;
			this.Completer = completer;
			this.CompleteTime = DateTime.Now;
		}

		#endregion

		#region Public Methods

		public abstract void CalculateTotalAmount();
		
		#endregion

		#region Private Methods

		/// <summary>
		/// 订单状态审核
		/// </summary>
		private void CheckStatus(OrderStatus requireStatus)
		{
			if (this.Status != requireStatus)
			{
				throw new HangerdException("订单状态异常，当前状态:{0}", CommonTools.GetEnumDescription(this.Status));
			}
		}

		#endregion
	}
}
